package edu.cmu.cs211.compression.tests;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Random;
import java.util.Map;

import javax.swing.text.html.HTMLDocument.Iterator;

import org.junit.Test;

import edu.cmu.cs211.compression.huffman.HuffmanCode;
import edu.cmu.cs211.compression.huffman.HuffmanCodeVisualizer;
import edu.cmu.cs211.compression.huffman.HuffmanCompressor;
import edu.cmu.cs211.compression.huffman.HuffmanNode;
import edu.cmu.cs211.compression.io.BitReader;
import edu.cmu.cs211.compression.io.BitWriter;
import edu.cmu.cs211.compression.io.InputStreamBitReader;
import edu.cmu.cs211.compression.io.OutputStreamBitWriter;

// This is a stub for you. Please write more tests!
public class HuffmanTest {
	@Test
	public void testRoundTrip () throws Exception
	{
		byte[] x = new byte [1];
		new Random (43).nextBytes (x);
		TestUtil.checkRoundTrip (new HuffmanCompressor (), x);
	}
	
    @Test
    public void simple() throws Exception {
        String[] tests = new String[] { "asdfddffaassdasdfs",
                                "asdfaaaaaaaadaaadaaaaaaafaaaaaaaaa",
                                "The red rear rikes to grrrrrrrrrrr" };
        for (int i = 0; i < tests.length; i++) {
                byte[] input = tests[i].getBytes("ASCII");
                TestUtil.checkRoundTrip(new HuffmanCompressor (),input);
        }
    }

    @Test
    public void testCompress() throws IOException
    {
    	Map<Byte, Integer> map = new HashMap<Byte, Integer>();
    	map.put((byte) 0x10, 50);
    	map.put((byte) 0x20, 25);
    	map.put((byte) 0x30, 15);
    	map.put((byte) 0x40, 40);
    	map.put((byte) 0x50, 75);
    	
    	HuffmanCode hc = new HuffmanCode(map);
    	
    	assertEquals("the only element in the queue", 205, hc.huffQueue.poll().getFreq());
    	
    	/*
    	// write header of tree into an output file
    	File f=new File("C:\\Users\\yyriver\\Desktop\\sample\\output.bin");
        FileOutputStream fop=new FileOutputStream(f);
        OutputStreamBitWriter out = new OutputStreamBitWriter(fop);
        hc.writeHeader(out);
        
        // read back in the header file and build a tree
        FileInputStream file = new FileInputStream(f);
        InputStreamBitReader reader = new InputStreamBitReader(file);
        HuffmanNode hn = hc.bitReaderToTree(reader);

        // compare the left most leaf of the original tree, vs the left most leaf of the tree that's built out of the header file
        while(hn.getLeft()!= null)
        	hn = hn.getLeft();
        HuffmanNode root = hc.root;
        while(root.getLeft()!=null)
        	root = root.getLeft();
        assertEquals("Read Header vs Read tree", hn.getValue(), root.getValue());
        */
    }

    
    @Test
    public void testInteger() throws Exception 
    {
    	int [] ints = new int[] {
    			1, 23, 45, 28, 40, 30, 21, 15
    	};
    	for(int i = 0; i < ints.length-2; i++)
    	{
    		byte[] in = new byte[] {
    				(byte)ints[i], (byte)ints[i+1], (byte)ints[i+2]
    		};
    		TestUtil.checkRoundTrip(new HuffmanCompressor (),in);
    	}
    }
    
    @Test
    public void stressTest() throws Exception
    {
    	for(int i = 0; i < 100; i++)
    	{
    		// generate a random string and convert it to hex
    		byte [] input = (Long.toHexString(Double.doubleToLongBits(Math.random()))).getBytes("ASCII");
    		TestUtil.checkRoundTrip(new HuffmanCompressor(), input);
    	}
    }
}
